<?php
/**
* Copyright 2009 Waag Society <http://www.waag.org>
* This file is part of Annotrax.
*
* Annotrax is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* Annotrax is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Annotrax.
* If not, see http://www.gnu.org/licenses/gpl.html
*/

?>
<?php
class AnnotationController extends Zend_Controller_Action{
	/**
	 * Implementation of Zend_Controller::init perform an access check and looks for a valid id
	 */
    public function init(){
        $request = $this->getRequest();
		// you must be logged in for add/edit/delete
        if( in_array( $request->action, array( 'add', 'edit', 'delete' ) ) ){
            if( ! Zend_Auth::getInstance()->hasIdentity() ){
                //$session = At_Factory::session();
				// remember what you were about to do in case login
                //$session->cache_uri = $request->getRequestUri();
				// after logging in, redirect back to cache_uri
                $this->_redirect( '/error/login' );
            }
		}
		if( null == $request->id ){
			$this->_redirect( '/error/notfound' );
		}
    }

	/**
	 * Output response as JSON. returns an array with the movie, channel and
	 * annotation plus the edit-form associated with this annotation.
	 *
	 * @return void
	 */
	public function jsonAction(){
		$request = $this->getRequest();

        $form       = new Default_Form_Annotate();
		$user = $this->_helper->user();
		
		if( $request->action == 'add' && null !== $request->channel ){
			$movie 		= new Default_Model_Movie( $request->id );
			$channel    = new Default_Model_Channel( $request->channel );
			//$annotation = new Default_Model_Annotation(
			//	array('movie_id' => $request->id, 'channel_id' => $request->channel ));
				$annotation = new Default_Model_Annotation(array(
					'movie_id' 	 => $request->id,
					'channel_id' => $request->channel,
					'user_id'	 => $user->id
				));
		}
		else if( $request->action == 'edit' || $request->action == 'json' ){
			$annotation = new Default_Model_Annotation( $request->id );
			$movie 		= new Default_Model_Movie( $annotation->movieId );
			$channel    = new Default_Model_Channel( $annotation->channelId );
	        $form->setAction('/annotation/edit/' . $annotation->id );
		}
		else{
			$response = array(
				'success'	=> false,
				'message'	=> array('invalid parameters given. did you specify id and channel?')
			);

			$this->_helper->json( $response );
		}

		$form->setChannel( $channel );
		$form->setAnnotation( $annotation );

		$response = array(
			'success'		=> true,
			'form'			=> (string) $form,
			'movies'		=> array( $movie->toArray() ),
			'channels'		=> array( $channel->toArray() ),
			'annotations'	=> array( $annotation->toArray() ),
		);

		// this is a backdoor: if response is provided as part of the reqeust, merge
		//var_dump( $request->response );
		if( null !== $request->response ){
			$response = array_merge( $response, $request->response );
		}

        $this->_helper->json( $response );
	}

	/**
	 * Edit annotation
	 *
	 * GET: if appropriate headers are set, JSON form is returned, HTML otherwise
	 * POST: if appropriate headers are set, validate the form and returns
	 * 		json response with form validations
	 */
    public function editAction(){
		$request = $this->getRequest();

		if( ! Zend_Auth::getInstance()->hasIdentity() ){
			$this->_forward( 'login', 'user' );
		}
		if( !$request->isPost() && ( $request->isXmlHttpRequest() || $request->format == 'json')){
			$this->_forward('json');
		}

		$user = $this->_helper->user();//At_Factory::user();
		$annotation = new Default_Model_Annotation( $request->id );

		if( $user->id !== $annotation->userId ){
			$this->_redirect( '/error/noaccess' );
		}

		$movie 		= new Default_Model_Movie( $annotation->movieId );
		$channel    = new Default_Model_Channel( $annotation->channelId );
        $form       = new Default_Form_Annotate();
		$n 			= new Default_Model_Annotation(array('movie_id' => $movie->id));

		$form->setChannel( $channel );
		$form->setAnnotation( $annotation );
        $form->setAction('/annotation/edit/' . $annotation->id );

		if( $request->isPost() ){
			if( null !== $request->cancel ){
				$this->_redirect(sprintf('/annotation/play/%d', $annotation->id));
				$this->_forward('delete');
			}
			else if( $form->isValid( $request->getPost() ) ){
				$keywords = array();
				$annotation->comment  = $request->comment;

				$annotation->setDuration( $request->duration )
							->setTime( $request->start );

				// @todo: wat nou als je open/single hebt? checken voor 1 keyword?
				// open/single is eigenlijk nogal onzin toch? - types vastleggen
				if( null !== $request->addKeywords ){
					foreach( explode(',', $request->addKeywords ) as $name ){
						$keywords[] = new Default_Model_Keyword( array('name' => $name ) );
					}
				}
				if( null !== $request->keywords ){
					foreach( (array) $request->keywords as $keyword ){
						$keywords[] = new Default_Model_Keyword( $keyword );
					}
				}

				$annotation->setKeywords( $keywords );
				$annotation->save();

				//@lodewijk: enzovoorts. validatie hier.
				// returns the newly created annotation in json
				if( $request->isXmlHttpRequest() || $request->format == 'json' ){
					$this->_forward( 'json', null, null, array('action' => 'edit', 'id' => $annotation->id ) );
					return;
				}

				$this->_redirect( '/annotation/play/' . $annotation->id );
			}
			else if( $request->isXmlHttpRequest() || $request->format == 'json' ){
				// reqeust was json, so form-errors will be returned as json
				$this->_forward( 'json', null, null, array(
					'response' => array(
						'success' => false,
						'errors' => $form->getErrors()
					)
				));
				return;
			}
		}

		$this->view->channels 	 = $movie->getChannels();
		$this->view->annotations = $n->fetchAll();
		$this->view->annotation = $annotation;
		$this->view->movie		= $movie;
		$this->view->form 		= $form;
    }

	/**
	 * Creates a new annotation
	 */
    public function addAction(){
		$request = $this->getRequest();

		if( ! Zend_Auth::getInstance()->hasIdentity() ){
			$this->_forward( 'login', 'user' );
		}
		else if( null == $request->channel ){
			$this->_redirect( '/error/notfound');
		}
		else if( !$request->isPost() && ( $request->isXmlHttpRequest() || $request->format == 'json')){
			$this->_forward('json');
			return;
		}
		else{
			$movie 		= new Default_Model_Movie( $request->id );
			$channel    = new Default_Model_Channel( $request->channel );

			if( null == $movie->title || null == $channel->name ){
				$this->_forward('/error/notfound');
			}
		}

		$user = $this->_helper->user(); //At_Factory::user();

        $form       = new Default_Form_Annotate();
		$annotation = new Default_Model_Annotation(array(
			'movie_id' 	 => $request->id,
			'channel_id' => $request->channel,
			'user_id'	 => $user->id
		));

		$form->setChannel( $channel );
		$form->setAnnotation( $annotation );
		$form->setAction( sprintf( '/annotation/add/%d/channel/%d', $movie->id, $channel->id ) );

		if( $request->isPost() ){
			if( null !== $request->cancel ){
				$this->_redirect(sprintf( '/annotation/play/%d', $annotation->id ));
			}
			if( null !== $request->cancel ){
				$this->_forward( 'play', 'movie', array( 'id' => $movie->id ) );
			}

			if( $form->isValid( $request->getPost() ) ){
				$keywords = array();
				$annotation->comment  = $request->comment;

				$annotation->setDuration( $request->duration )
							->setTime( $request->start );

				// @todo: wat nou als je open/single hebt? checken voor 1 keyword?
				// open/single is eigenlijk nogal onzin toch? - types vastleggen
				
				/* [LL] removed
				if( null !== $request->addKeywords ){
	
					foreach( explode(',', $request->addKeywords ) as $name ){
						$keywords[] = new Default_Model_Keyword( array('name' => $name ) );
					}
				}
				if( null !== $request->keywords ){
					foreach( $request->keywords as $keyword ){
						$keywords[] = new Default_Model_Keyword( $keyword );
					}
				}
				*/
				if( null !== $request->keywords ){ //[LL] added

					foreach( explode(',', $request->keywords ) as $id ){
						$keywords[] = new Default_Model_Keyword( array('id' => $id ) );
					}
				}
				
			
				$annotation->setKeywords( $keywords );
				$annotation->save();

				//@lodewijk: enzovoorts. validatie hier.
				// return validated results as json: id is now known.
				if( $request->isXmlHttpRequest() || $request->format == 'json' ){
					$this->_forward( 'json', null, null, array(
						'action' => 'edit',
						'id' => $annotation->id
					));
					return;
				}

				$this->_redirect( '/annotation/play/' . $annotation->id );
			}
			else if( $request->isXmlHttpRequest() || $request->format == 'json' ){
				$this->_forward( 'json', null, null, array(
					'response' => array(
						'success' => false,
						'errors' => $form->getErrors()
					)
				));
				return;
			}
		}
		$n = new Default_Model_Annotation(array('movie_id' => $movie->id));

		$this->view->channels 	 = $movie->getChannels();
		$this->view->annotations = $n->fetchAll();
		$this->view->annotation  = $annotation;
		$this->view->movie		 = $movie;
		$this->view->form 		 = $form;
    }

	/**
	 * delete selected annotation
	 */
    public function deleteAction(){
		$request	= $this->getRequest();
		$user		= $this->_helper->user(); //At_Factory::user();
		$annotation = new Default_Model_Annotation( $request->id );

		if( $annotation->userId !== $user->id ){
			$this->_redirect( '/error/noaccess' );
		}

		$movieId 	= $annotation->movieId;//do this before delete!

		$annotation->delete();

		$this->_redirect( '/movie/play/' . $movieId );
    }

	/**
	 * show a player with annotation
	 */
    public function playAction(){
		$request = $this->getRequest();

		$annotation = new Default_Model_Annotation( $request->id );
		$movie 		= new Default_Model_Movie( $annotation->movieId );
		$n 			= new Default_Model_Annotation(array('movie_id' => $movie->id));

//		$movie->filename = $annotation->getMovieUri();

		$this->view->channels    = $movie->getChannels();
		$this->view->annotations = $n->fetchAll();
		$this->view->annotation  = $annotation;
		$this->view->movie		 = $movie;
  	}
}
